package com.lp.multi.thread.example06;

/**
 * @author: lp
 * @create: 2021-06-22 16:23
 * @description: 死锁例子
 * 当一个线程拥有2个以上的对象锁,容易发生死锁
 * 产生死锁必要条件：
 * 1.
 * 2.
 * 3.
 * 4.
 *
 */
//多个线程互相拥有对方的资源，就会死锁
public class DeadLock {
    public static void main(String[] args) {
        new Makeup("皇后",true).start();
        new Makeup("白雪公主",false).start();
    }

}

//镜子
class Mirror{

}

//口红
class Lipstick{

}

class Makeup extends Thread{
    //只有一个镜子
    private static Mirror mirror= new Mirror();
    //只有一支口红
    private static Lipstick lipstick= new Lipstick();
    //是否先拿镜子
    private boolean isFirstGetMirror = true;
    private String girlName;


    @Override
    public void run() {
        try {
            //嵌套2把锁
            //make();
            make2();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public Makeup(String girlName,boolean isFirstGetMirror){
        this.girlName =girlName;
        this.isFirstGetMirror = isFirstGetMirror;
    }

    //化妆需要同时拿着镜子和口红
    //嵌套锁代码块
    private void make() throws InterruptedException {
        if(isFirstGetMirror){
            synchronized (mirror){
                System.out.println(girlName+"拿到了镜子，先照了1秒钟，准备去拿口红!");
                Thread.sleep(1000);
                synchronized (lipstick){
                    System.out.println(girlName+"拿到了口红，准备开始化妆!");
                }
            }
        }else{
            synchronized (lipstick){
                System.out.println(girlName+"拿到了口红，先看了2秒口红,准备去拿镜子!");
                Thread.sleep(2000);
                synchronized (mirror){
                    System.out.println(girlName+"拿到了镜子，准备开始化妆!");
                }
            }
        }
    }

    //化妆需要同时拿着镜子和口红
    private void make2() throws InterruptedException {
        if(isFirstGetMirror){
            synchronized (mirror){
                System.out.println(girlName+"拿到了镜子，先照了1秒钟，准备去拿口红!");
                Thread.sleep(1000);
            }
            synchronized (lipstick){
                System.out.println(girlName+"拿到了口红，准备开始化妆!");
            }
        }else{
            synchronized (lipstick){
                System.out.println(girlName+"拿到了口红，先看了2秒口红,准备去拿镜子!");
                Thread.sleep(2000);
            }
            synchronized (mirror){
                System.out.println(girlName+"拿到了镜子，准备开始化妆!");
            }
        }
    }


}
